import router from "/@/router/index";
import type { RouteRecordRaw } from "vue-router";

interface ServerRouterData {
  name: string;
  children: ServerRouterData[];
}

/**
 * ======================== 动态计算路由 =======================
 * 先获取routet/modules下的所有文件
 * 进行比对后，route.addRoute 加入已实例后的全局路由中
 */
const localRoute: RouteRecordRaw[] = [];
// @ts-ignore
const req = require.context("@/router/modules", false, /\.ts$/);
req.keys().forEach((item: { default: RouteRecordRaw | RouteRecordRaw[] }) => {
  const route = req(item).default;
  if (Array.isArray(item)) {
    return localRoute.push(...route);
  } else {
    localRoute.push(route);
  }
});

/**
 * 根据路由name对总体的路由进行合并比较
 * @param serverRouterData 服务器的路由数据
 * @param localRoute 当前本地已经配置好的路由
 * @return 本层次对比后的结果
 * */
const marge = (
  serverRouterData: ServerRouterData[],
  localRoute: RouteRecordRaw[]
): { route: RouteRecordRaw[]; menu: RouteRecordRaw[] } => {
  const route: RouteRecordRaw[] = [];
  const menu: RouteRecordRaw[] = [];
  const Slength = serverRouterData.length;
  for (let i = 0; i < Slength; i++) {
    const item = serverRouterData[i];
    const localData = localRoute.find(s => s.name === item.name) || undefined;
    if (localData) {
      let margeChild: { route: RouteRecordRaw[]; menu: RouteRecordRaw[] } = {
        route: [],
        menu: []
      };
      // 先排除children，如果有必要对比children在对比加入
      const children = localData.children;
      Reflect.deleteProperty(localData, "children");
      const menuCopy = { ...localData };
      if (children?.length && item.children?.length) {
        margeChild = marge(item.children, children);
      }
      if (margeChild?.route.length) {
        localData.children = margeChild.route;
      }
      if (margeChild?.menu.length) {
        menuCopy.children = margeChild.menu;
      }
      if (menuCopy.meta && !menuCopy.meta.hide) {
        Reflect.deleteProperty(menuCopy, "component");
        menu.push(menuCopy);
      }
      route.push(localData);
    }
  }
  return {
    route,
    menu
  };
};
/**
 * 根据后台返回的路由name对总体的路由进行合并比较
 * @param serverRouterData 当前路由名称的name
 * @return 对比后的所有结果
 * */
export const computed = (
  serverRouterData: ServerRouterData[]
): RouteRecordRaw[] => {
  const data = marge(serverRouterData, localRoute);
  data.route.forEach(v => router.addRoute("rootRoute", v));
  return data.menu;
};
